{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 文件操作和os模块"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## python 文件操作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 文件本身的操作 （python 内置）\n",
    "\n",
    "- 格式: `f = open('文件路径','打开方式')`\n",
    "\n",
    "    - 打开方式：\n",
    "        - w: 文件不存在会创建，存在会清空\n",
    "        - r: 读模式，文件不存在会报错，存在则读取\n",
    "        - a：追加模式，文件不存在则新建，存在则在末尾追加内容\n",
    "        - b: **以二进制打开文件**\n",
    "\n",
    "- `f.close()`\n",
    "- `f.read()`: 读取文件\n",
    "- `f.readline()`: 读取一行文件\n",
    "- `f.readlines()`: 将文件中的内容读取到序列当中\n",
    "- `f.write()`:  写入文件\n",
    "- `f.writelines()`: 将序列写入文件中"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 文件信息读取\n",
    "\n",
    "#打开文件\n",
    "\n",
    "f=open('./python_try.txt','r')  #io 的文件流对象\n",
    "#打开时，光标在第一行开头\n",
    "# 'a': 光标在最后\n",
    "# ./ 表示当前目录\n",
    "f\n",
    "#读取内容并输出\n",
    "content = f.read(5) # 读5个字符，光标后移\n",
    "print(content)\n",
    "content2=f.read() # 整个读完\n",
    "content2\n",
    "# # 关闭文件\n",
    "f.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 一次读取一行并打印\n",
    "f=open('./python_try.txt','r')  \n",
    "line = f.readline()\n",
    "while len(line)>0:\n",
    "    print(line,end='')\n",
    "    line = f.readline()\n",
    "f.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# # 一次读取所有行  readlines,如果是大文件，建议上面的方式\n",
    "f=open('./python_try.txt','r') \n",
    "lines = f.readlines()\n",
    "for i in lines:\n",
    "    print(i,end='')\n",
    "f.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 文件写入操作\n",
    "f=open('./b.txt','w') \n",
    "f.write('Hey you!~\\n')\n",
    "f.write('How are you!\\n')\n",
    "f.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# f.wirte()\n",
    "f=open('./b.txt','w') \n",
    "f.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a=['Hello Python!\\n','Hello you!\\n','Hello HTML\\n']\n",
    "f=open('./b.txt','w')   # 覆盖原文件\n",
    "f.writelines(a)\n",
    "f.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a=['Hello Python!\\n','Hello you!\\n','Hello HTML\\n']\n",
    "f=open('./b.txt','a')  # 在末尾追加\n",
    "f.writelines(a)\n",
    "f.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('./b.txt', 'r') as f:\n",
    "    print(f.read())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 添加系统路径"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "\n",
    "#sys.path.append('C:\\\\Users\\\\illus\\\\OneDrive\\\\创业\\\\value_compass_project\\\\data')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## os 模块： 系统中文件和文件夹的操作\n",
    "\n",
    "- 导入：`import os`\n",
    "\n",
    "- 方法\n",
    "\n",
    "    `os.getcwd()` : 获取当前工作路径\n",
    "\n",
    "    `os.chdir()`: 改变路径\n",
    "\n",
    "    `os.listdir()`: 获取指定文件夹内的内容\n",
    "\n",
    "    `os.mkdir()`: 创建一个新目录\n",
    "\n",
    "    `os.rmdir()`: 移除一个目录（**必须是空目录**, 否则会报错）\n",
    "\n",
    "    `os.rename('old_name','new_name')`: 修改文件或文件夹名称\n",
    "\n",
    "    `os.stat()`：获取文件的相关信息\n",
    "\n",
    "    `os.getenv()`: 获取环境变量\n",
    "\n",
    "    `os.exit()`: 退出,关闭当前操作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 获取当前工作路径， `os.getcwd()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "# os.getcwd()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 改变工作路径， `os.chdir()`\n",
    "- 绝对路径 v.s. 相对路径"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 绝对路径，无论在哪里都可以找到\n",
    "# os.chdir('C:/Users/illus/OneDrive/CUPL/Teaching')   \n",
    "\n",
    "# 相对路径，相对于文件本身的位置定位\n",
    "    # ./： 在当前文件所在的文件夹目录下\n",
    "    # ../ 对于当前文件夹的上一级文件夹\n",
    "# os.chdir('../../raw-data')  \n",
    "\n",
    "os.getcwd()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 获取指定文件夹的内容 `os.listdir()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.listdir()\n",
    "\n",
    "# a=os.listdir()\n",
    "# for i in a:\n",
    "#     print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 当前os的模块值\n",
    "\n",
    "- `os.path` 模块主要用于获取文件的属性\n",
    "\n",
    "- `os.name` 返回当前操作系统的类型，当前注册了3个值：分别是posix , nt , java， 对应linux/windows/java虚拟机\n",
    "\n",
    "- `os.sep` 获取当前系统的分隔符\n",
    "\n",
    "- `os.linesep`  获取当前系统的换行符"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.sep"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "os.linesep"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 其它应用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 获取文件或文件夹的绝对路径 os.path.abspath()\n",
    "import os\n",
    "os.path.abspath('master.txt')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 判断文件是否存在 os.path.exists()\n",
    "os.path.exists('master')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 获取路径中的文件名  os.path.basename(path)\n",
    "file='a/b/d/c/e.txt'   \n",
    "os.path.basename(file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 获取路径中的目录名字（去掉文件名）  os.path.dirname(path)\n",
    "os.path.dirname(file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 路径拼接 os.path.join(path,file)\n",
    "path='a/b'\n",
    "file='a.txt'\n",
    "os.path.join(path,file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a=os.path.join(path,\"/\",file)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 判断是否是文件\n",
    "# os.path.isfile('master')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 判断是否是文件夹\n",
    "# os.path.isdir('master')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Exercise\n",
    "# 自定义目录复制文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mycopy(file1,file2):\n",
    "    '''\n",
    "    文件复制函数\n",
    "    '''\n",
    "    # 打开文件源和目标文件\n",
    "    f1=open(file1,'rb')   # 图片，声音，视频等是二进制存储的，单独的'r','w'是文本文件，\n",
    "                           # 加上'b'， 所有文件都可以复制了！！！\n",
    "    f2=open(file2,'wb')\n",
    "    #循环读取并写入，实现复制\n",
    "    content = f1.readline()\n",
    "    while len(content)>0:\n",
    "        f2.write(content)\n",
    "        content=f1.readline()\n",
    "    # 关闭目标文件\n",
    "    f1.close()\n",
    "    f2.close()\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "# 自定义目录复制函数\n",
    "def copydd(dir1,dir2):\n",
    "    # 复制目录里的所有文件信息\n",
    "    dlist=os.listdir(dir1)\n",
    "    # 创建新目录\n",
    "    os.mkdir(dir2)\n",
    "    \n",
    "    # 遍历所有文件并复制\n",
    "    for f in dlist:\n",
    "        # 为遍历的文件添加目录信息\n",
    "        file1 = os.path.join(dir1,f) # 原文件\n",
    "        file2=os.path.join(dir2,f)  # 目标文件\n",
    "        # 判断是否是文件\n",
    "        if os.path.isfile(file1):\n",
    "            mycopy(file1,file2)  # 调用自定义函数复制文件\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# os.chdir('C:\\\\Users\\\\illus\\\\OneDrive\\\\CUPL\\\\Teaching\\\\python')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 测试\n",
    "# copydd('./笔记','./copy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 自定义目录复制函数\n",
    "def copydd(dir1,dir2):\n",
    "    # 复制目录里的所有文件信息\n",
    "    dlist=os.listdir(dir1)\n",
    "    # 创建新目录\n",
    "    os.mkdir(dir2)\n",
    "    \n",
    "    # 遍历所有文件并复制\n",
    "    for f in dlist:\n",
    "        # 为遍历的文件添加目录信息\n",
    "        file1 = os.path.join(dir1,f) # 原文件\n",
    "        file2=os.path.join(dir2,f)  # 目标文件\n",
    "        # 判断是否是文件\n",
    "        if os.path.isfile(file1):\n",
    "            mycopy(file1,file2)  # 调用自定义函数复制文件\n",
    "        if os.path.isdir(file1): # 判断是否是目录\n",
    "            copydd(file1,file2) # 递归调用，自己调用自己，实现子目录的赋值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算目录的大小\n",
    "def calculate_size(dir1):\n",
    "    # 读取目录里的所有文件信息\n",
    "    dlist=os.listdir(dir1)\n",
    "    # 初始大小为0\n",
    "    size=0\n",
    "    # 遍历所有文件并计算大小\n",
    "    for f in dlist:\n",
    "        # 判断是否是文件\n",
    "        if os.path.isfile(f):\n",
    "            size += os.path.getsize(f)  # 调用自定义函数复制文件\n",
    "        if os.path.isdir(f): # 判断是否是目录\n",
    "            temp=calculate_size(f) #递归调用，自己调用自己，实现子目录的赋值\n",
    "            size += temp\n",
    "    return size"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 测试\n",
    "# dir1='C:\\\\Users\\\\illus\\\\OneDrive\\\\CUPL\\\\Teaching\\\\python'\n",
    "# size=calculate_size(dir1)\n",
    "# size"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
